package cn.edu.seu.ssny.config.shiro;

import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Import;

/**
 * 授权
 */

@Configuration
@Import(ShiroManager.class)
public class ShiroConfig {

	@Bean(name = "realm")
	@DependsOn("lifecycleBeanPostProcessor")
	@ConditionalOnMissingBean
	public Realm realm() {
		return new SsnyRealm();
	}
	
	 /**
     * 用户授权信息Cache
     */
    @Bean(name = "shiroCacheManager")
    @ConditionalOnMissingBean
    public CacheManager cacheManager() {
        return new MemoryConstrainedCacheManager();
    }

    @Bean(name = "securityManager")
    @ConditionalOnMissingBean
    public DefaultSecurityManager securityManager() {
        DefaultSecurityManager sm = new DefaultWebSecurityManager();
        sm.setCacheManager(cacheManager());
        return sm;
    }

	@Bean(name = "shiroFilter")
	@DependsOn("securityManager")
	@ConditionalOnMissingBean
	public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultSecurityManager securityManager, Realm realm) {
		securityManager.setRealm(realm);

		ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
		shiroFilter.setSecurityManager(securityManager);

		Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
		filterChainDefinitionMap.put("/assets/**", "anon");
		filterChainDefinitionMap.put("/register", "anon");
		filterChainDefinitionMap.put("/login", "anon");


		filterChainDefinitionMap.put("/admin", "perms[system:admin:index]");
		
		filterChainDefinitionMap.put("/admin/user/index", "perms[system:user:index]");
		filterChainDefinitionMap.put("/admin/user/list", "perms[system:user:list]");
		filterChainDefinitionMap.put("/admin/user/add", "perms[system:user:add]");
		filterChainDefinitionMap.put("/admin/user/edit*", "perms[system:user:edit]");
		filterChainDefinitionMap.put("/admin/user/delete*", "perms[system:user:delete]");
		filterChainDefinitionMap.put("/admin/user/grant/**", "perms[system:user:grant]");
		
		filterChainDefinitionMap.put("/admin/role/index", "perms[system:role:index]");
		filterChainDefinitionMap.put("/admin/role/add", "perms[system:role:add]");
		filterChainDefinitionMap.put("/admin/role/edit*", "perms[system:role:edit]");
		filterChainDefinitionMap.put("/admin/role/delete*", "perms[system:role:delete*]");
		filterChainDefinitionMap.put("/admin/role/grant/**", "perms[system:role:grant]");
		
		filterChainDefinitionMap.put("/admin/resource/index", "perms[system:resource:index]");
		filterChainDefinitionMap.put("/admin/resource/add", "perms[system:resource:add]");
		filterChainDefinitionMap.put("/admin/resource/edit*", "perms[system:resource:edit]");
		filterChainDefinitionMap.put("/admin/resource/delete*", "perms[system:resource:deleteB*]");


		filterChainDefinitionMap.put("/admin/project/index", "perms[system:project:index]");
		filterChainDefinitionMap.put("/admin/project/list", "perms[system:project:list]");
		filterChainDefinitionMap.put("/admin/project/add", "perms[system:project:add]");
		filterChainDefinitionMap.put("/admin/project/edit*", "perms[system:project:edit]");
		filterChainDefinitionMap.put("/admin/project/display/edit", "perms[system:project:edit]");
		filterChainDefinitionMap.put("/admin/project/delete*", "perms[system:project:delete]");

		filterChainDefinitionMap.put("/admin/device/index", "perms[system:device:index]");
		filterChainDefinitionMap.put("/admin/device/list", "perms[system:device:list]");
		filterChainDefinitionMap.put("/admin/device/add", "perms[system:device:add]");
		filterChainDefinitionMap.put("/admin/device/edit*", "perms[system:device:edit]");
		filterChainDefinitionMap.put("/admin/device/display/edit", "perms[system:device:edit]");
		filterChainDefinitionMap.put("/admin/device/delete*", "perms[system:device:delete]");

		filterChainDefinitionMap.put("/admin/gateway/index", "perms[system:gateway:index]");
		filterChainDefinitionMap.put("/admin/gateway/list", "perms[system:gateway:list]");
		filterChainDefinitionMap.put("/admin/gateway/add", "perms[system:gateway:add]");
		filterChainDefinitionMap.put("/admin/gateway/edit*", "perms[system:gateway:edit]");
		filterChainDefinitionMap.put("/admin/gateway/delete", "perms[system:gateway:delete]");


		filterChainDefinitionMap.put("/web/project/alarm/index", "perms[system:alarm:index]");
		filterChainDefinitionMap.put("/web/project/alarm/list", "perms[system:alarm:list]");
		filterChainDefinitionMap.put("/web/project/alarm/add", "perms[system:alarm:add]");
		filterChainDefinitionMap.put("/web/project/alarm/address*", "perms[system:alarm:address]");


		filterChainDefinitionMap.put("/web/project/device", "perms[system:data:index]");

		filterChainDefinitionMap.put("/web/project/livedata", "perms[system:data:index]");

		filterChainDefinitionMap.put("/web/project/usage", "perms[system:usage:index]");

		filterChainDefinitionMap.put("/web/log/index", "perms[system:log:index]");

		filterChainDefinitionMap.put("/web/data/index", "perms[system:data:index]");

		filterChainDefinitionMap.put("/admin/**", "authc");
		filterChainDefinitionMap.put("/*","authc");
		shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMap);

		shiroFilter.setLoginUrl("/login");
		shiroFilter.setSuccessUrl("/index");
		shiroFilter.setUnauthorizedUrl("/previlige/no");
		return shiroFilter;
	}
}
